//
//  HHPSecure.m
//
//  Created by 韩红坡 on 2016/12/24.
//  Copyright © 2016年 韩红坡. All rights reserved.
//

#import "HHPSecure.h"
#import "RSA.h"
#import "NSData+AESEncry.h"
#import "GTMBase64.h"
#import "HHPSecureManager.h"

@implementation HHPSecure
#pragma mark - RSA+AES加解密
+ (NSDictionary *)encryptAESDictionary:(NSDictionary *)dict
{
    return [self encryptAESDictionary:dict withPublicKey:[self getPublicKey]];
}

+ (NSDictionary *)encryptDictionary:(NSDictionary *)dict
{
    return [self encryptDictionary:dict withPublicKey:[self getPublicKey]];
}

+ (NSString *)encryptString:(NSString *)str
{
    return [self encryptString:str withPublicKey:[self getPublicKey]];
}

+ (NSString *)decryptString:(NSString *)str withFixedString:(NSString *)fixedString withRandomString:(NSString *)randomString
{
    NSData *jsonData = [GTMBase64 decodeString:str];
    
    NSData *randomData = [GTMBase64 decodeString:randomString];
    
    NSString *randomStr = [[NSString alloc] initWithData:randomData encoding:NSUTF8StringEncoding];
    
    NSString *key = [self calculateKeyWithFixedString:fixedString withRandomString:randomStr];
    
    NSData *decryptedData = [jsonData AES256DecryptWithKey:[key dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSString *decryptedString = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
    
    return decryptedString;
}

+ (NSDictionary *)encryptDictionary:(NSDictionary *)dict withPublicKey:(NSString *)publicKey
{
    NSAssert(publicKey != nil, @"RSA公钥为空，请检查公钥文件是否添加到工程中");
    
    if (!dict || (dict && dict.count == 0)) {
        return @{@"params":@"", @"encryptKey":@""};
    }
    
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:NULL];
    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    HHPSecureManager *manager = [HHPSecureManager shareManager];
    dispatch_semaphore_wait(manager.signalEncrypt, DISPATCH_TIME_FOREVER);
    NSString *encryptedString = [RSA encryptString:jsonString publicKey:publicKey];
    dispatch_semaphore_signal(manager.signalEncrypt);
    if (encryptedString && publicKey) {
        return @{@"params":encryptedString, @"encryptKey":publicKey};
    } else {
        return @{@"params":@"", @"encryptKey":@""};
    }
}

+ (NSDictionary *)encryptAESDictionary:(NSDictionary *)dict withPublicKey:(NSString *)publicKey
{
    NSAssert(publicKey != nil, @"RSA公钥为空，请检查公钥文件是否添加到工程中");
    
    if (!dict || (dict && dict.count == 0)) {
        return @{@"params":@"", @"encryptKey":@""};
    }
    
    NSString *randomKeyString = [self create32bitString];
    
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:NULL];
    
    NSData *encryptedData = [jsonData AES256EncryptWithKey:[randomKeyString dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSString *encryptedString = [GTMBase64 stringByEncodingData:encryptedData];

    HHPSecureManager *manager = [HHPSecureManager shareManager];
    dispatch_semaphore_wait(manager.signalEncrypt, DISPATCH_TIME_FOREVER);
    NSString *encryptedRandomKeyString = [RSA encryptString:randomKeyString publicKey:publicKey];
    dispatch_semaphore_signal(manager.signalEncrypt);
    
    if (encryptedString && encryptedRandomKeyString) {
        return @{@"params":encryptedString, @"encryptKey":encryptedRandomKeyString};
    } else {
        return @{@"params":@"", @"encryptKey":@""};
    }
}

+ (NSString *)encryptString:(NSString *)str withPublicKey:(NSString *)publicKey
{
    NSAssert(publicKey != nil, @"RSA公钥为空，请检查公钥文件是否添加到工程中");
    
    if (!str || (str && str.length == 0)) {
        return @"";
    }
    
    HHPSecureManager *manager = [HHPSecureManager shareManager];
    dispatch_semaphore_wait(manager.signalEncrypt, DISPATCH_TIME_FOREVER);
    NSString *encryptedString = [RSA encryptString:str publicKey:publicKey];
    dispatch_semaphore_signal(manager.signalEncrypt);
    
    return (encryptedString ? : @"");
}

#pragma mark - AES加解密
+ (NSString *)encryptDictionary:(NSDictionary *)dict withAESKey:(NSString *)key
{
    NSAssert(key != nil, @"AES秘钥不能为空");
    NSAssert(key.length == 32, @"AES秘钥必须为32位");
    
    if (!dict || (dict && dict.count == 0)) {
        return @"";
    }
    
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:NULL];
    
    NSData *encryptedData = [jsonData AES256EncryptWithKey:[key dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSString *encryptedString = [GTMBase64 stringByEncodingData:encryptedData];
    
    return encryptedString;
}

+ (NSString *)encryptString:(NSString *)string withAESKey:(NSString *)key
{
    NSAssert(key != nil, @"AES秘钥不能为空");
    NSAssert(key.length == 32, @"AES秘钥必须为32位");
    
    if (!string || (string.length == 0)) {
        return @"";
    }
    
    NSData *jsonData = [string dataUsingEncoding:NSUTF8StringEncoding];
    
    NSData *encryptedData = [jsonData AES256EncryptWithKey:[key dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSString *encryptedString = [GTMBase64 stringByEncodingData:encryptedData];
    
    return encryptedString;
}

+ (NSString *)decryptString:(NSString *)encryptString withAESKey:(NSString *)key
{
    NSAssert(key != nil, @"AES秘钥不能为空");
    NSAssert(key.length == 32, @"AES秘钥必须为32位");
    
    if (!encryptString || (encryptString.length == 0)) {
        return @"";
    }
    
    NSData *jsonData = [GTMBase64 decodeString:encryptString];
    
    NSData *decryptedData = [jsonData AES256DecryptWithKey:[key dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSString *decryptedString = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
    
    return decryptedString;
}

+ (NSDictionary *)decryptDictString:(NSString *)encryptDictString withAESKey:(NSString *)key
{
    NSAssert(key != nil, @"AES秘钥不能为空");
    NSAssert(key.length == 32, @"AES秘钥必须为32位");
    
    if (!encryptDictString || (encryptDictString.length == 0)) {
        return @{};
    }
    
    NSData *jsonData = [GTMBase64 decodeString:encryptDictString];
    
    NSData *decryptedData = [jsonData AES256DecryptWithKey:[key dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:decryptedData options:0 error:nil];
    
    return dict;
}

#pragma mark - private methods
+ (NSString *)getPublicKey
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"rsa_public_key" ofType:@"pem"];
    NSString *publicKey = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
    
    return publicKey;
}

+ (NSString *)create32bitString
{
    char data[32];
    
    for (int x=0;x<32;data[x++] = (char)('A' + (arc4random_uniform(26))));
    
    return [[NSString alloc] initWithBytes:data length:32 encoding:NSUTF8StringEncoding];
    
}

+ (NSString *)calculateKeyWithFixedString:(NSString *)fixedString withRandomString:(NSString *)randomString
{
    NSMutableString *key = [NSMutableString string];
    for (int i = 0; i < 16; i++) {
        [key appendString:[fixedString substringWithRange:NSMakeRange(i, 1)]];
        [key appendString:[randomString substringWithRange:NSMakeRange(i, 1)]];
    }
    
    return key;
}

@end
